$(function() {
	
	var nodes = new Array();		//节点集合
	var lines = new Array();		//线集合
	var nexus = new Array();		//关系集合
	var initx,inity;				//画线时的起点坐标
	var mouseStatus = 0;			//鼠标状态，按下鼠标时为1，松开为0
	var checks = {};				//选中对象，一次只有一个
		
	
	var startNodePoint = {			//开始节点相关信息
		x1 : 0,
		y1 : 0,
		x2 : 0,
		y2 : 0,
		name : "",
		no : ""
	};
	
	//对外暴露的方法
	$.Mflow = {
		getData : function(){
			var data = {};
			data.nodes = nodes;
			data.lines = lines;
			data.nexus = nexus;
			return data;
		},
		getNodes : function(){
			return nodes;
		},
		getLines : function(){
			return lines;
		},
		getNexus : function(){
			return nexus;
		},
		judgeFlow : function(){
			var hasStart = false;
			var hasEnd = false;
			for (var i=0; i<nexus.length; i++) {
				if (nexus[i].from=="开始") {
					hasStart = true;
				}
				if (nexus[i].to=="结束") {
					hasEnd = true;
				}
			}
			if (!hasStart) {
				$.MsgBox.Alert("系统提示", "开始结点不存在或未连接其它节点");
				return false;
			}
			if (!hasEnd) {
				$.MsgBox.Alert("系统提示", "结束结点不存在或未连接其它节点");
				return false;
			}
			if (nexus.length<3) {
				$.MsgBox.Alert("系统提示", "操作节点过少，至少需要2个或2个以上的操作节点（不包含开始和结束）");
				return false;
			}
			return true;
		},
		getFlowData : function(){
			var startN, endN;
			var data = [];
			for (var i=0; i<nexus.length; i++) {
				if (nexus[i].from=="开始") {
					startN = nexus[i].to; 
				}
				if (nexus[i].to=="结束") {
					endN = nexus[i].from; 
				}
			}
			for (var i=0; i<nexus.length; i++) {
				if (nexus[i].from!="开始" && nexus[i].to!="结束") {
					var flowData = {};
					
					
					if (nexus[i].from==startN) {
						flowData.from_status = 1;
					}else if (nexus[i].from==endN) {
						flowData.from_status = -1;
					}else {
						flowData.from_status = 0;
					}
					
					if (nexus[i].to==startN) {
						flowData.to_status = 1;
					}else if (nexus[i].to==endN) {
						flowData.to_status = -1;
					}else {
						flowData.to_status = 0;
					}
					
					
					flowData.from = nexus[i].fromId;
					flowData.to = nexus[i].toId;
					data.push(flowData);
				}
			}
			return data;
		},
		loadData : function(data){
			data = eval("("+data+")");
			nodes = data.nodes;
			lines = data.lines;
			nexus = data.nexus;
			debugger;
			for (var i=0;i<nodes.length;i++) {
				var node = $("<div></div>").addClass(nodes[i].className).text(nodes[i].no);
				$(node).css({"opacity":"1", "z-index":nodes[i].zIndex, "left":nodes[i].left, "top":nodes[i].top});
				$(node).attr({id : nodes[i].id});
				$(node).appendTo($(".draw_canvas"));
				addEventOnNodes(node);
			}
			for (var i=0;i<lines.length;i++) {
				var svg = "<svg width=\""+$('#draw_canvas').width()+"\" height=\""+$('#draw_canvas').height()+"\"><defs><marker id=\"arrow\" markerWidth=\"4\" markerHeight=\"4\" refx=\"0\" refy=\"2\" orient=\"auto\" markerUnits=\"strokeWidth\">" + 
				"<path id=\"path\" d=\"M0,0 L0,4 L3,2 z\" fill=\"#7E8FC0\" /> </marker> </defs>" +
				"<line id=\""+lines[i].id+"\" x1=\""+lines[i].x1+"\" y1=\""+lines[i].y1+"\" x2=\""+lines[i].x2+"\" y2=\""+lines[i].y2+"\" stroke=\"#7E8FC0\" stroke-width=\"3\" marker-end=\"url(#arrow)\" /> </svg>";
				$(svg).appendTo(".draw_canvas");
			}
		}
	}
	
	//根据no在画布中查找节点
	function getNodeByText(text){
		var nodes = $('.ui_widget_content');
		for (var i in nodes) {
			var node = nodes[i];
			if (node.innerText==text) {
				return node;
			}
		}
	}
	
	//判断节点是否在画布中
	function nodeInDrow(text){
		var nodes = $('.ui_widget_content');
		var n=0;
		for (var i in nodes) {
			var node = nodes[i];
			if (node.innerText==text) {
				n++;
			}
		}
		if (n>=2) {
			return true;
		}
		return false;
	}
	
	//根据线id得到父级对象
	function getSvgByLineId(id){
		var line = document.getElementById(id);
		return line.parentElement;
	}
	
	//获取编号
	function getDomId(){
		return $.now();
	}
	
	//根据线条id查找开始节点
	function getStartNodeByLineId(id){
		for (var i in nexus) {
			var dn = nexus[i];
			if (dn.line == id) {
				return getNodeByText(dn.from);
			}
		}
	}
	
	//根据线条id查找结束节点
	function getEndNodeByLineId(id){
		for (var i in nexus) {
			var dn = nexus[i];
			if (dn.line == id) {
				return getNodeByText(dn.to);
			}
		}
	}
	
	//处理节点移动时线条跟着移动
	function moveLineByNodeMove(nl,point){
		if (nl.beari == "from") {
			//结束节点信息
			var endNd = getEndNodeByLineId(nl.id);
			
			var endNodePoint = {};
			endNodePoint.x1 = endNd.offsetLeft;
			endNodePoint.y1 = endNd.offsetTop;
			endNodePoint.x2 = endNd.offsetLeft + endNd.offsetWidth;
			endNodePoint.y2 = endNd.offsetTop + endNd.offsetHeight;
			endNodePoint.no = endNd.innerText;
			
			//重新画线
			resetLine(point, endNodePoint, nl.id);
			
		}else if (nl.beari == "to"){
			//开始节点信息
			var startNd = getStartNodeByLineId(nl.id);
			
			var startNodePoint = {};
			startNodePoint.x1 = startNd.offsetLeft;
			startNodePoint.y1 = startNd.offsetTop;
			startNodePoint.x2 = startNd.offsetLeft + startNd.offsetWidth;
			startNodePoint.y2 = startNd.offsetTop + startNd.offsetHeight;
			startNodePoint.no = startNd.innerText;
			
			//重新画线
			resetLine(startNodePoint, point, nl.id);
		}
	}
	
	//重画线条，传入开始节点，结束节点，线条
	function resetLine(startNodePoint, endNodePoint, id){
		var line = document.getElementById(id);
		if (startNodePoint.x2 < endNodePoint.x1 && startNodePoint.y2 < endNodePoint.y1){														//1
			line.x1.baseVal.value = startNodePoint.x2;
			line.y1.baseVal.value = startNodePoint.y2;
			line.x2.baseVal.value = endNodePoint.x1;
			line.y2.baseVal.value = endNodePoint.y1 - 7;
		}else if (startNodePoint.x2 > endNodePoint.x1 && startNodePoint.y2 < endNodePoint.y1 && startNodePoint.x1 < endNodePoint.x1){			//2
			line.x1.baseVal.value = (startNodePoint.x2 + endNodePoint.x1) / 2;
			line.y1.baseVal.value = startNodePoint.y2;
			line.x2.baseVal.value = (startNodePoint.x2 + endNodePoint.x1) / 2;
			line.y2.baseVal.value = endNodePoint.y1 - 10;
		}else if (startNodePoint.x2 > endNodePoint.x2 && startNodePoint.y2 < endNodePoint.y1 && startNodePoint.x1 < endNodePoint.x2){			//3
			line.x1.baseVal.value = (startNodePoint.x1 + endNodePoint.x2) / 2;
			line.y1.baseVal.value = startNodePoint.y2;
			line.x2.baseVal.value = (startNodePoint.x1 + endNodePoint.x2) / 2;
			line.y2.baseVal.value = endNodePoint.y1 - 8;
		}else if (startNodePoint.x1 > endNodePoint.x2 && startNodePoint.y2 < endNodePoint.y1){													//4
			line.x1.baseVal.value = startNodePoint.x1;
			line.y1.baseVal.value = startNodePoint.y2;
			line.x2.baseVal.value = endNodePoint.x2;
			line.y2.baseVal.value = endNodePoint.y1 - 8;
		}else if (startNodePoint.y2 > endNodePoint.y1 && startNodePoint.y2 < endNodePoint.y2 && startNodePoint.x2 < endNodePoint.x1){			//5
			line.x1.baseVal.value = startNodePoint.x2;
			line.y1.baseVal.value = (startNodePoint.y2 + endNodePoint.y1) / 2;
			line.x2.baseVal.value = endNodePoint.x1-10;
			line.y2.baseVal.value = (startNodePoint.y2 + endNodePoint.y1) / 2;
		}else if (startNodePoint.y2 > endNodePoint.y2 && startNodePoint.y1 < endNodePoint.y2 && startNodePoint.x2 < endNodePoint.x1){			//6
			line.x1.baseVal.value = startNodePoint.x2;
			line.y1.baseVal.value = (startNodePoint.y1 + endNodePoint.y2) / 2;
			line.x2.baseVal.value = endNodePoint.x1-10;
			line.y2.baseVal.value = (startNodePoint.y1 + endNodePoint.y2) / 2;
		}else if (startNodePoint.y2 > endNodePoint.y1 && startNodePoint.y2 < endNodePoint.y2 && startNodePoint.x1 > endNodePoint.x2){			//7
			line.x1.baseVal.value = startNodePoint.x1;
			line.y1.baseVal.value = (startNodePoint.y2 + endNodePoint.y1) / 2;
			line.x2.baseVal.value = endNodePoint.x2 + 10;
			line.y2.baseVal.value = (startNodePoint.y2 + endNodePoint.y1) / 2;
		}else if (startNodePoint.y2 > endNodePoint.y2 && startNodePoint.y1 < endNodePoint.y2 && startNodePoint.x1 > endNodePoint.x2){			//8
			line.x1.baseVal.value = startNodePoint.x1;
			line.y1.baseVal.value = (startNodePoint.y1 + endNodePoint.y2) / 2;
			line.x2.baseVal.value = endNodePoint.x2 + 10;
			line.y2.baseVal.value = (startNodePoint.y1 + endNodePoint.y2) / 2;
		}else if (startNodePoint.x2 < endNodePoint.x1 && startNodePoint.y1 > endNodePoint.y2){													//9
			line.x1.baseVal.value = startNodePoint.x2;
			line.y1.baseVal.value = startNodePoint.y1;
			line.x2.baseVal.value = endNodePoint.x1 - 5;
			line.y2.baseVal.value = endNodePoint.y2 + 5;
		}else if (startNodePoint.x2 > endNodePoint.x1 && startNodePoint.x2 < endNodePoint.x2 && startNodePoint.y1 > endNodePoint.y2){			//10
			line.x1.baseVal.value = (startNodePoint.x2 + endNodePoint.x1) / 2;
			line.y1.baseVal.value = startNodePoint.y1;
			line.x2.baseVal.value = (startNodePoint.x2 + endNodePoint.x1) / 2;
			line.y2.baseVal.value = endNodePoint.y2 + 10;
		}else if (startNodePoint.x2 > endNodePoint.x2 && startNodePoint.x1 < endNodePoint.x2 && startNodePoint.y1 > endNodePoint.y2){			//11	
			line.x1.baseVal.value = (startNodePoint.x1 + endNodePoint.x2) / 2;
			line.y1.baseVal.value = startNodePoint.y1;
			line.x2.baseVal.value = (startNodePoint.x1 + endNodePoint.x2) / 2;
			line.y2.baseVal.value = endNodePoint.y2 + 10;
		}else if (startNodePoint.x1 > endNodePoint.x2 && startNodePoint.y1 > endNodePoint.y2){													//12
			line.x1.baseVal.value = startNodePoint.x1;
			line.y1.baseVal.value = startNodePoint.y1;
			line.x2.baseVal.value = endNodePoint.x2 + 5;
			line.y2.baseVal.value = endNodePoint.y2 + 5;
		}
		
		//更新数据
		for (var i=0;i<nodes.length;i++) {
			var node = nodes[i];
			var left = $('#'+node.id)[0].offsetLeft;
			var top = $('#'+node.id)[0].offsetTop;
			node.left = left;
			node.top = top;
		}
		
		for (var i=0;i<lines.length;i++) {
			var line = lines[i];
			var x1 = $('#'+line.id)[0].x1.baseVal.value;
			var y1 = $('#'+line.id)[0].y1.baseVal.value;
			var x2 = $('#'+line.id)[0].x2.baseVal.value;
			var y2 = $('#'+line.id)[0].y2.baseVal.value;
			line.x1 = x1;
			line.y1 = y1;
			line.x2 = x2;
			line.y2 = y2;
		}
	}
	
	//是否在节点集合中
	function inNodes(id){
		for (var i in nodes) {
			var obj = nodes[i];
			if (obj.no==id) {
				return obj;
			}
		}
		return null;
	}
	
	//该线条是否已经画过了
	function inLines(from,to){
		var s = false;
		for (var i=0; i<nexus.length; i++) {
			if (nexus[i].from==from && nexus[i].to==to) {
				s = true;
			}
		}
		if (s) {
			return true;
		}else {
			return false;
		}
	}
	
	//为节点绑定事件
	function addEventOnNodes(node){
		//添加鼠标拖拽和画线事件
		$(node).on("mousedown",function(e){
			if (e.which==3) {
				startNodePoint.x1 = this.offsetLeft;
				startNodePoint.y1 = this.offsetTop;
				
				startNodePoint.x2 = this.offsetLeft + this.offsetWidth;
				startNodePoint.y2 = this.offsetTop + this.offsetHeight;
				startNodePoint.name = this.innerText;
				startNodePoint.id = this.id;
				startNodePoint.left = this.style.left;
				startNodePoint.top = this.style.top;
				startNodePoint.zIndex = this.style.zIndex;
				startNodePoint.className = this.className;
				
				var lx = e.pageX - $('.index_menu')[0].offsetWidth - $('.flow_left')[0].offsetWidth;
				var ly = e.pageY - $('.index_header')[0].offsetHeight - $('.index_subheader')[0].offsetHeight - $('.flow_top')[0].offsetHeight - $('.index_subheader')[0].offsetHeight;
				
				if (mouseStatus==0) {
					initx = lx;
					inity = ly;
					
					var line = "<svg width=\""+$('#draw_canvas').width()+"\" height=\""+$('#draw_canvas').height()+"\"><defs><marker id=\"arrow\" markerWidth=\"4\" markerHeight=\"4\" refx=\"0\" refy=\"2\" orient=\"auto\" markerUnits=\"strokeWidth\">" + 
					"<path id=\"path\" d=\"M0,0 L0,4 L3,2 z\" fill=\"red\" /> </marker> </defs>" +
					"<line id=\"line\" x1=\""+lx+"\" y1=\""+ly+"\" x2=\""+lx+"\" y2=\""+ly+"\" stroke=\"red\" stroke-width=\"3\" marker-end=\"url(#arrow)\" /> </svg>";
					$(line).appendTo(".draw_canvas");
					mouseStatus = 1;
				}
				
				//当线的终点不是在节点上松开时，删除该线条
				$('#draw_canvas').mouseup(function(e){
					$('#draw_canvas').off('mousemove'); 

					var line = document.getElementById("line");
					if (line!=undefined && line != null &&
						line.parentElement!=undefined && line.parentElement != null ) {
						line.parentElement.remove();
					}

					mouseStatus = 0;
					startNodePoint.x1 = 0;
					startNodePoint.y1 = 0;
			
					startNodePoint.x2 = 0;
					startNodePoint.y2 = 0;
				});
				
				//两节点之间画线时，显示的红色虚线位置
				$('#draw_canvas').mousemove(function(e) {
					var line = document.getElementById("line");
					
					var offset = $(this).offset();
					var lx = (e.pageX - offset.left);
					var ly = (e.pageY - offset.top - 10);
					
					line.x2.baseVal.value = lx;
					line.y2.baseVal.value = ly;
				});
				
				//画线
				$('.ui_widget_content').mouseup(function(e){
					$('#draw_canvas').off('mousemove');
					
					//如果开始节点和结束节点是同一节点，则不画线
					if (startNodePoint.name==this.innerText) {
						var line = document.getElementById("line");
						if (line!=undefined && line != null &&
							line.parentElement!=undefined && line.parentElement != null ) {
							line.parentElement.remove();
						}

						mouseStatus = 0;
						startNodePoint.x1 = 0;
						startNodePoint.y1 = 0;
				
						startNodePoint.x2 = 0;
						startNodePoint.y2 = 0;
						return;
					}
					
					//如果该线条已经画过了，则不重复画
					if (inLines(startNodePoint.name, this.innerText)) {
						var line = document.getElementById("line");
						if (line!=undefined && line != null &&
							line.parentElement!=undefined && line.parentElement != null ) {
							line.parentElement.remove();
						}

						mouseStatus = 0;
						startNodePoint.x1 = 0;
						startNodePoint.y1 = 0;
				
						startNodePoint.x2 = 0;
						startNodePoint.y2 = 0;
						return;
					}
					
					var endNodePoint = {
						x1 : this.offsetLeft,
						y1 : this.offsetTop - 3,
						x2 : this.offsetLeft + this.offsetWidth,
						y2 : this.offsetTop + this.offsetHeight - 3
					}

					var line = document.getElementById("line");
					var path = document.getElementById("path");
					if (line!=undefined && line != null &&
						path!=undefined && path != null) {
						path.setAttribute("fill", "#7E8FC0");
						path.removeAttribute("id");
						
						var line_id = getDomId();
						
						line.style.stroke = "#7E8FC0";
						line.setAttribute("id",line_id);
						
						//重新画线
						resetLine(startNodePoint, endNodePoint, line_id);
						
						//添加线对象
						var dline = {};
						dline.id = line_id;
						dline.x1 = line.x1.baseVal.value;
						dline.x2 = line.x2.baseVal.value;
						dline.y1 = line.y1.baseVal.value;
						dline.y2 = line.y2.baseVal.value;
						lines[lines.length] = dline;
						
						//添加开始节点
						var dstartNode = {};
						dstartNode.no = startNodePoint.name;
						dstartNode.id = startNodePoint.id;
						dstartNode.left = startNodePoint.left;
						dstartNode.top = startNodePoint.top;
						dstartNode.zIndex = startNodePoint.zIndex;
						dstartNode.className = startNodePoint.className;
						dstartNode.lines = [];
						
						var nline = {};
						nline.beari = "from";
						nline.id = line_id;
						dstartNode.lines.push(nline);
						var sd = inNodes(dstartNode.no);
						if (sd==null){
							nodes[nodes.length] = dstartNode;
						}else {
							sd.lines.push(nline);
						}
						
						//添加结束节点
						var dendNode = {};
						dendNode.no = this.innerText;
						dendNode.id = this.id;
						dendNode.left = this.style.left;
						dendNode.top = this.style.top;
						dendNode.zIndex = this.style.zIndex;
						dendNode.className = this.className;
						dendNode.lines = [];
						var nline2 = {};
						nline2.beari = "to";
						nline2.id = line_id;
						dendNode.lines.push(nline2);
						var jd = inNodes(dendNode.no);
						if (jd==null){
							nodes[nodes.length] = dendNode;
						}else {
							jd.lines.push(nline2);
						}
						
						//添加关系对象
						var dnexus = {};
						dnexus.from = dstartNode.no;
						dnexus.fromId = dstartNode.id;
						dnexus.to = dendNode.no;
						dnexus.toId = dendNode.id;
						dnexus.line = line_id;
						nexus[nexus.length] = dnexus;
						
						startNodePoint.x1 = 0;
						startNodePoint.y1 = 0;
				
						startNodePoint.x2 = 0;
						startNodePoint.y2 = 0;
					}
				});
				
			}else if (e.which==1){	
				//拖动节点时，重新计算线条的位置
				$('.ui_widget_content').mouseup(function(e){
					var endNodePoint = {
						x1 : this.offsetLeft,
						y1 : this.offsetTop,
						x2 : this.offsetLeft + this.offsetWidth,
						y2 : this.offsetTop + this.offsetHeight,
						name : this.innerText
					}
					var direction = "";
					for (var i in nodes) {
						var nd = nodes[i];
						if (nd.no==endNodePoint.name) {
							var nl = nd.lines;
							for (var j in nl) {
								moveLineByNodeMove(nl[j],endNodePoint);
							}
						}
					}
					$('.ui_widget_content').off("mouseup");
				});
			}
		});
		
		//添加点击事件
		$(node).on("click",function(e){
			if (this.style.border=="0px none rgb(0, 0, 0)" ||
				this.style.border=="") {
				$(this).css("border","1px solid red");
				if (checks.id!=undefined && checks.id!=null) {
					var node = getNodeByText(checks.id);
					node.style.border = "0px none rgb(0, 0, 0)";
					checks = {};
				}
				checks.type = "node";
				checks.id = this.innerText;
			}else {
				$(this).css("border","0px none rgb(0, 0, 0)");
				checks = {};
			}
		})
		
		//添加拖拽
		$(node).draggable({
			stack: "#draw_canvas div",
			containment : "#draw_canvas",
			opacity: 0.4, 
			helper: "original"
		});
	}
	
	//禁用鼠标右键菜单
	$(document).bind("contextmenu",function(e){
        return false;
    });
	
	//左侧列表点击事件
	$(".menu a").on("click", function(){
		$(this).next().toggle();
	});
	
	//左侧拖拽操作及画线
	$("li.node").draggable({
		containment : ".flow_canvas_div",
		cursor: "move",
		opacity : 0.5,
		cursorAt: { top: 15, left: 100 },
		helper: function(e) {
			if (e.currentTarget.className.indexOf("node ot")!=-1) {
				return $("<div class=\"ui_widget_content other\" id="+$(e.currentTarget).data("value")+" >"+e.currentTarget.innerText+"</div>");
			}else if (e.currentTarget.className.indexOf("node rp")!=-1){
				return $("<div class=\"ui_widget_content repair\" id="+$(e.currentTarget).data("value")+" >"+e.currentTarget.innerText+"</div>");
			}else {
				return $("<div class=\"ui_widget_content\" id="+$(e.currentTarget).data("value")+" >"+e.currentTarget.innerText+"</div>");
			}
			
		},
		stop: function(e,ui){
			if (ui.position.left>203 && ui.position.left<1000 &&
				ui.position.top>0 && ui.position.top<700) {
				
				var x = ui.position.left - $('.flow_left')[0].offsetWidth;
				var y = ui.position.top;
				if (nodeInDrow(ui.helper[0].innerText)) {
					$.MsgBox.Alert("系统提示", "该节点已存在画布中，不可重复拖拽！");
					return;
				}
				var node = $("<div></div>").addClass(ui.helper[0].className).text(ui.helper[0].innerText);
				$(node).css({"opacity":"1","z-index":"4",left:x+"px",top:y+"px"});
				$(node).attr({id : ui.helper[0].id});
				$(node).appendTo($(".draw_canvas"));
				
				addEventOnNodes(node);
			}
		}
	});
	
	$(document).keydown(function (e){
		if (e.keyCode==46) {
			if (checks.id!=undefined && checks.id!=null) {
				var nd = getNodeByText(checks.id);
				for (var i in nodes) {			//循环所有节点
					var node = nodes[i];
					if (nd.innerText==node.no) {	//如果是当前节点
						var ndlines = node.lines;
						for (var j = 0; j<ndlines.length; j++) {
							var line = ndlines[j];
							
							for (var l in lines) {
								var sline = lines[l];
								if (sline.id == line.id) {
									lines.splice(l,1);			//删除线集合中符合的记录
								}
							}
							
							for (var n in nexus) {				//删除关系集合中符合的记录
								var nexu = nexus[n];
								if (nexu.line==line.id) {
									nexus.splice(n,1);
								}
							}
							
							for (var nl in nodes) {			//删除节点集合中符合的记录
								var ndd = nodes[nl];
								var nddlines = ndd.lines;
								for (var ll in nddlines) {
									if (line.id==nddlines[ll].id) {
										nddlines.splice(ll,1);
										if (ndd.no==nd.innerText) {
											j--;
										}
									}
								}
							}
							
							var svg = getSvgByLineId(line.id);
							svg.parentNode.removeChild(svg);	//删除该对象下线条集合对应的实体线
						}
					}
				}
				nd.parentNode.removeChild(nd);					//移除该节点
				checks = {};
			}
		}
	})
})